package com.poly.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.poly.common.core.tools.utils.Func;
import com.poly.common.core.utils.ConvertUtils;
import com.poly.common.core.utils.IdUtil;
import com.poly.system.domain.SysAppMenuAuth;
import com.poly.system.enums.AppMenuAuthTypeEnum;
import com.poly.system.mapper.SysAppMenuAuthMapper;
import com.poly.system.pojo.dto.SysAppMenuAuthDTO;
import com.poly.system.pojo.query.SysAppMenuAuthQuery;
import com.poly.system.pojo.vo.SysAppMenuAuthVO;
import com.poly.system.service.ISysAppMenuAuthService;
import com.poly.system.service.ISysDeptService;
import com.poly.system.service.ISysRoleService;
import com.poly.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 应用菜单授权Service业务层处理
 *
 * @author poly
 * @date 2024-01-02
 */
@Service
public class SysAppMenuAuthServiceImpl extends ServiceImpl<SysAppMenuAuthMapper, SysAppMenuAuth> implements ISysAppMenuAuthService {
    @Autowired
    private ISysDeptService deptService;

    @Autowired
    private ISysRoleService roleService;

    @Autowired
    private ISysUserService userService;

    /**
     * 获取查询对象
     *
     * @param query
     * @return
     */
    public LambdaQueryWrapper<SysAppMenuAuth> getWrapper(SysAppMenuAuthQuery query) {
        LambdaQueryWrapper<SysAppMenuAuth> wrapper = null;
        if (Func.isNotEmpty(query)) {
            wrapper = Wrappers.<SysAppMenuAuth>lambdaQuery();
            if (Func.isNotEmpty(query.getId())) {
                wrapper.eq(SysAppMenuAuth::getId, query.getId());
            }
            if (Func.isNotEmpty(query.getAuthType())) {
                wrapper.eq(SysAppMenuAuth::getAuthType, query.getAuthType());
            }
            if (Func.isNotEmpty(query.getAuthId())) {
                wrapper.eq(SysAppMenuAuth::getAuthId, query.getAuthId());
            }
            if (Func.isNotEmpty(query.getMenuId())) {
                wrapper.eq(SysAppMenuAuth::getMenuId, query.getMenuId());
            }
        }
        return wrapper;
    }

    /**
     * 查询APP能力菜单列表
     *
     * @param query
     * @return
     */
    public List<SysAppMenuAuthVO> list(SysAppMenuAuthQuery query) {
        List<SysAppMenuAuthVO> list = ConvertUtils.convert(list(getWrapper(query)), SysAppMenuAuthVO.class);
        if (Func.isNotEmpty(list)) {
            List<Long> orgIdList = list.stream().filter(p -> AppMenuAuthTypeEnum.DEPT.getValue().equals(p.getAuthType()))
                    .map(SysAppMenuAuthVO::getAuthId).distinct().collect(Collectors.toList());
            List<Long> roleIdList = list.stream().filter(p -> AppMenuAuthTypeEnum.ROLE.getValue().equals(p.getAuthType()))
                    .map(SysAppMenuAuthVO::getAuthId).distinct().collect(Collectors.toList());
            List<Long> userIdList = new ArrayList<>();
            userIdList.addAll(list.stream().filter(p -> AppMenuAuthTypeEnum.USER.getValue().equals(p.getAuthType()))
                    .map(SysAppMenuAuthVO::getAuthId).distinct().collect(Collectors.toList()));
            userIdList.addAll(list.stream().map(SysAppMenuAuthVO::getCreateBy).distinct().collect(Collectors.toList()));
            Map<Long, String> orgNameMap = null;
            if (Func.isNotEmpty(orgIdList)) {
                orgNameMap = deptService.getDeptNameMap(orgIdList);
            }
            Map<Long, String> roleNameMap = null;
            if (Func.isNotEmpty(roleIdList)) {
                roleNameMap = roleService.getRoleNameMap(roleIdList);
            }
            Map<Long, String> userNameMap = null;
            if (Func.isNotEmpty(userIdList)) {
                userNameMap = userService.getUserNameMap(userIdList);
            }
            for (SysAppMenuAuthVO item : list) {
                item.setAuthTypeDesc(AppMenuAuthTypeEnum.getName(item.getAuthType()));
                if (AppMenuAuthTypeEnum.DEPT.getValue().equals(item.getAuthType())
                        && null != orgNameMap && orgNameMap.containsKey(item.getAuthId())) {
                    item.setAuthDesc(orgNameMap.get(item.getAuthId()));
                } else if (AppMenuAuthTypeEnum.ROLE.getValue().equals(item.getAuthType())
                        && null != roleNameMap && roleNameMap.containsKey(item.getAuthId())) {
                    item.setAuthDesc(roleNameMap.get(item.getAuthId()));
                } else if (AppMenuAuthTypeEnum.USER.getValue().equals(item.getAuthType())
                        && null != userNameMap && userNameMap.containsKey(item.getAuthId())) {
                    item.setAuthDesc(userNameMap.get(item.getAuthId()));
                }
                if (null != userNameMap && userNameMap.containsKey(item.getCreateBy())) {
                    item.setCreateByDesc(userNameMap.get(item.getCreateBy()));
                }
            }
        }
        return list;
    }

    /**
     * APP能力授权
     *
     * @return
     */
    public Boolean auth(SysAppMenuAuthDTO model, Long userId) {
        List<SysAppMenuAuth> appMenuAuthList = new ArrayList<>();
        for (Long menuId : model.getMenuIdList()) {
            if (count(Wrappers.<SysAppMenuAuth>lambdaQuery()
                    .eq(SysAppMenuAuth::getAuthType, model.getAuthType())
                    .eq(SysAppMenuAuth::getAuthId, model.getAuthId())
                    .eq(SysAppMenuAuth::getMenuId, menuId)) > 0) {
                throw new IllegalArgumentException("授权类型的对象已经授权！");
            }
            SysAppMenuAuth appMenuAuth = new SysAppMenuAuth();
            appMenuAuth.setId(IdUtil.getId());
            appMenuAuth.setAuthId(model.getAuthId());
            appMenuAuth.setMenuId(menuId);
            appMenuAuth.setAuthType(model.getAuthType());
            appMenuAuth.setCreateBy(userId);
            appMenuAuth.setCreateTime(new Date());
            appMenuAuthList.add(appMenuAuth);
        }
        if (appMenuAuthList.size() > 0) {
            return saveBatch(appMenuAuthList);
        }
        return false;
    }

    public Boolean cancelAuth(List<Long> idList) {
        if (Func.isNotEmpty(idList)) {
            return removeBatchByIds(idList);
        }
        return true;
    }

    public List<Long> getMenuIdListByOrgId(Long orgId, List<Long> roleIdList, Long userId) {
        List<Long> menuIdList = new ArrayList<>();
        List<Long> authIdList = new ArrayList<>();
        if (null != orgId) {
            authIdList.add(orgId);
        }
        if (Func.isNotEmpty(roleIdList)) {
            authIdList.addAll(roleIdList);
        }
        if (null != userId) {
            authIdList.add(userId);
        }
        if (Func.isNotEmpty(authIdList)) {
            List<SysAppMenuAuth> list = list(Wrappers.<SysAppMenuAuth>lambdaQuery().in(SysAppMenuAuth::getAuthId, authIdList));
            if (Func.isNotEmpty(list)) {
                if (null != orgId) {
                    menuIdList.addAll(list.stream().filter(p -> orgId.equals(p.getAuthId()) && AppMenuAuthTypeEnum.DEPT.getValue().equals(p.getAuthType())).map(SysAppMenuAuth::getMenuId).collect(Collectors.toList()));
                }
                if (Func.isNotEmpty(roleIdList)) {
                    menuIdList.addAll(list.stream().filter(p -> roleIdList.contains(p.getAuthId()) && AppMenuAuthTypeEnum.ROLE.getValue().equals(p.getAuthType())).map(SysAppMenuAuth::getMenuId).collect(Collectors.toList()));
                }
                if (null != userId) {
                    menuIdList.addAll(list.stream().filter(p -> userId.equals(p.getAuthId()) && AppMenuAuthTypeEnum.USER.getValue().equals(p.getAuthType())).map(SysAppMenuAuth::getMenuId).collect(Collectors.toList()));
                }
            }
        }
        return menuIdList.stream().distinct().collect(Collectors.toList());
    }
}
